<template>
  <el-dialog
    title="生成代码"
    :visible.sync="dialogVisible"
    fullscreen
  >
    <el-form ref="formRules" inline :model="form" :rules="formRules">
      <el-form-item label="包名" prop="moduleName">
        <el-input v-model="form.moduleName" placeholder="请输入包名" />
      </el-form-item>
      <el-form-item label="主键生成策略" prop="primaryKeyCreatePolicy">
        <el-select v-model="form.primaryKeyCreatePolicy" placeholder="请选择">
          <el-option
            v-for="item in primaryKeyCreatePolicySelectArray"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="表备注" prop="tableComment">
        <el-input v-model="form.tableComment" placeholder="请输入表备注" />
      </el-form-item>
      <el-form-item label="导入/导出" prop="tableComment">
        <el-switch
          v-model="form.inOut"
          disabled
        />
      </el-form-item>
    </el-form>
    <el-table v-loading="table.loading" :data="table.data" border style="width: 100%">
      <el-table-column align="center" prop="columnName" label="名称" />
      <el-table-column align="center" prop="dataType" label="类型" />
      <el-table-column align="center" prop="dataType" label="是否为主键">
        <template slot-scope="{row}">
          <el-switch v-model="row.primaryKey" disabled />
        </template>
      </el-table-column>
      <el-table-column align="center" prop="dataType" label="是否可编辑">
        <template slot-scope="{row}">
          <el-switch
            v-model="row.haveEdit"
            :disabled="row.primaryKey"
          />
        </template>
      </el-table-column>
      <el-table-column align="center" prop="columnComment" label="是否可导入导出">
        <template slot-scope="{row}">
          <el-switch
            v-model="row.inOut"
            @change="changeInOut"
          />
        </template>
      </el-table-column>
      <el-table-column align="center" prop="columnComment" label="是否必填">
        <template slot-scope="{row}">
          <el-switch
            v-model="row.required"
            :disabled="row.primaryKey || row.fieldInputType==='CREATE_TIME' || row.fieldInputType==='UPDATE_TIME'"
            @change="changeRequired"
          />
        </template>
      </el-table-column>
      <el-table-column align="center" prop="columnComment" label="注释">
        <template slot-scope="{row}">
          <el-input v-model="row.columnComment" type="text" />
        </template>
      </el-table-column>
      <el-table-column align="center" prop="columnComment" label="列表查询">
        <template slot-scope="{row}">
          <el-select
            v-model="row.fieldSearchType"
            :disabled="row.joinDict!=='' || row.fieldInputType==='IMAGE_UPLOAD' || row.fieldInputType==='RICH_TEXT'"
            clearable
            placeholder="请选择"
            @change="changeFieldSearchType(row)"
          >
            <el-option
              v-for="item in fieldSearchTypeSelectArray"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </template>
      </el-table-column>
      <el-table-column align="center" prop="columnComment" label="添加/编辑输入框">
        <template slot-scope="{row}">
          <el-select
            v-model="row.fieldInputType"
            :disabled="row.primaryKey || row.joinDict!==''"
            placeholder="请选择"
            @change="changeFieldInputType(row)"
          >
            <el-option
              v-for="item in fieldInputTypeSelectArray"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </template>
      </el-table-column>
      <el-table-column align="center" prop="columnComment" label="列表显示类型">
        <template slot-scope="{row}">
          <el-select
            v-model="row.fieldShowType"
            :disabled="row.primaryKey || row.joinDict!==''
              || row.fieldInputType==='IMAGE_UPLOAD' || row.fieldInputType==='RICH_TEXT'
              || row.fieldInputType==='CREATE_TIME' || row.fieldInputType==='UPDATE_TIME'"
            placeholder="请选择"
            @change="changeFieldShowType(row)"
          >
            <el-option
              v-for="item in fieldShowTypeSelectArray"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </template>
      </el-table-column>
      <el-table-column align="center" prop="joinDict" label="关联字典">
        <template slot-scope="scope">
          <el-select
            v-model="scope.row.joinDict"
            :disabled="scope.row.primaryKey"
            clearable
            placeholder="请选择"
            @change="changeTableJoinDictSelect(scope.$index)"
          >
            <el-option
              v-for="item in joinDictSelectArray"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </template>
      </el-table-column>
      <!--      <el-table-column align="center" label="操作" fixed="right" width="100px">
        <el-button-group class="operation">
          <el-button type="text">详情</el-button>
        </el-button-group>
      </el-table-column>-->
    </el-table>
    <el-divider />
    <div>
      <div>
        一对多表结构关联
        <el-switch v-model="oneToMany.open" style="margin-left: 10px" />
        <div v-show="oneToMany.open" style="margin-top: 10px">
          <el-select v-model="oneToMany.joinField" clearable placeholder="请选择关联字段">
            <el-option
              v-for="item in table.data"
              :key="item.columnName"
              :label="item.columnName"
              :value="item.columnName"
            />
          </el-select>
          <el-select v-model="oneToMany.joinTable" clearable placeholder="请选择关联表" @change="changeJoinTable()">
            <el-option
              v-for="item in allTableArray"
              :key="item.tableName"
              :label="item.tableName"
              :value="item.tableName"
            />
          </el-select>
          <el-select v-model="oneToMany.joinTableField" clearable placeholder="请选择关联表字段">
            <el-option
              v-for="item in oneToManyJoinFieldArray"
              :key="item.columnName"
              :label="item.columnName"
              :value="item.columnName"
            />
          </el-select>
          主键生成策略：
          <el-select v-model="oneToMany.primaryKeyCreatePolicy" placeholder="请选择">
            <el-option
              v-for="item in primaryKeyCreatePolicySelectArray"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
          <div>
            <el-table v-loading="oneToMany.tableLoading" :data="oneToMany.tableFieldList" border style="width: 100%;margin-top: 10px">
              <el-table-column align="center" prop="columnName" label="名称" />
              <el-table-column align="center" prop="dataType" label="类型" />
              <el-table-column align="center" prop="dataType" label="是否为主键">
                <template slot-scope="{row}">
                  <el-switch v-model="row.primaryKey" />
                </template>
              </el-table-column>
              <el-table-column align="center" prop="dataType" label="是否可编辑">
                <template slot-scope="{row}">
                  <el-switch
                    v-model="row.haveEdit"
                    :disabled="row.primaryKey"
                  />
                </template>
              </el-table-column>
              <el-table-column align="center" prop="columnComment" label="是否必填">
                <template slot-scope="{row}">
                  <el-switch
                    v-model="row.required"
                    :disabled="row.primaryKey || row.fieldInputType==='CREATE_TIME' || row.fieldInputType==='UPDATE_TIME'"
                    @change="changeOneTwoManyRequired"
                  />
                </template>
              </el-table-column>
              <el-table-column align="center" prop="columnComment" label="注释">
                <template slot-scope="{row}">
                  <el-input v-model="row.columnComment" type="text" />
                </template>
              </el-table-column>
              <el-table-column align="center" prop="columnComment" label="列表查询">
                <template slot-scope="{row}">
                  <el-select
                    v-model="row.fieldSearchType"
                    :disabled="row.joinDict!=='' || row.fieldInputType==='IMAGE_UPLOAD' || row.fieldInputType==='RICH_TEXT'"
                    clearable
                    placeholder="请选择"
                    @change="changeFieldSearchType(row)"
                  >
                    <el-option
                      v-for="item in fieldSearchTypeSelectArray"
                      :key="item.value"
                      :label="item.label"
                      :value="item.value"
                    />
                  </el-select>
                </template>
              </el-table-column>
              <el-table-column align="center" prop="columnComment" label="添加/编辑输入框">
                <template slot-scope="{row}">
                  <el-select
                    v-model="row.fieldInputType"
                    :disabled="row.primaryKey || row.joinDict!==''"
                    placeholder="请选择"
                    @change="changeFieldInputType(row)"
                  >
                    <el-option
                      v-for="item in fieldInputTypeSelectArray"
                      :key="item.value"
                      :label="item.label"
                      :value="item.value"
                    />
                  </el-select>
                </template>
              </el-table-column>
              <el-table-column align="center" prop="columnComment" label="列表显示类型">
                <template slot-scope="{row}">
                  <el-select
                    v-model="row.fieldShowType"
                    :disabled="row.primaryKey || row.joinDict!==''
                      || row.fieldInputType==='IMAGE_UPLOAD' || row.fieldInputType==='RICH_TEXT'
                      || row.fieldInputType==='CREATE_TIME' || row.fieldInputType==='UPDATE_TIME'"
                    placeholder="请选择"
                    @change="changeFieldShowType(row)"
                  >
                    <el-option
                      v-for="item in fieldShowTypeSelectArray"
                      :key="item.value"
                      :label="item.label"
                      :value="item.value"
                    />
                  </el-select>
                </template>
              </el-table-column>
              <el-table-column align="center" prop="joinDict" label="关联字典">
                <template slot-scope="scope">
                  <el-select
                    v-model="scope.row.joinDict"
                    :disabled="scope.row.primaryKey"
                    clearable
                    placeholder="请选择"
                    @change="changeOneToManyTableJoinDictSelect(scope.$index)"
                  >
                    <el-option
                      v-for="item in joinDictSelectArray"
                      :key="item.value"
                      :label="item.label"
                      :value="item.value"
                    />
                  </el-select>
                </template>
              </el-table-column>
              <!--      <el-table-column align="center" label="操作" fixed="right" width="100px">
                <el-button-group class="operation">
                  <el-button type="text">详情</el-button>
                </el-button-group>
              </el-table-column>-->
            </el-table>
          </div>
        </div>
      </div>
    </div>
    <span slot="footer" class="dialog-footer">
      <el-button @click="dialogVisible = false">取 消</el-button>
      <el-button type="primary" @click="generate">生 成</el-button>
    </span>
  </el-dialog>
</template>

<script>
import { getFieldByTable, getFieldInputType
  , getPrimaryKeyCreatePolicy
  , getFieldSearchType, getFieldShowType, generateCode } from '@/api/code-generate'
import {
  getAllTable
} from '@/api/code-generate/table'
import { getSysDictList } from '@/api/common/dict'

export default {
  name: 'GenerateCode',
  data() {
    return {
      dialogVisible: false,
      // 字段在列表中显示的类型
      fieldShowTypeSelectArray: [],
      defaultFieldShowType: null,
      // 搜索字段list
      fieldSearchTypeSelectArray: [],
      // 输入字段list
      fieldInputTypeSelectArray: [],
      // 主键生成策略list
      primaryKeyCreatePolicySelectArray: [],
      // 关联字典list
      joinDictSelectArray: [],
      allTableArray: [],
      // 一对多关联属性
      oneToMany: {
        open: false,
        joinTable: '',
        joinField: '',
        joinTableField: '',
        tableFieldList: null,
        tableLoading: false,
        primaryKeyCreatePolicy: '',
        required: false
      },
      // 一对多关联字段数组
      oneToManyJoinFieldArray: [],
      table: {
        data: null,
        loading: false
      },
      form: {
        moduleName: null,
        primaryKeyCreatePolicy: null,
        tableName: null,
        tableComment: null,
        inOut: false,
        required: false
      },
      formRules: {
        moduleName: [
          { required: true, message: '请输入包名', trigger: 'blur' }
        ]
      }
    }
  },
  methods: {
    open(tableName, tableComment) {
      this.form.tableName = tableName
      this.form.tableComment = tableComment
      this.dialogVisible = true
      this.getFieldShowTypeData()
      this.getFieldSearchTypeData()
      this.getFieldInputTypeData()
      this.getAllTableData()
      this.getPrimaryKeyCreatePolicyData()
      this.getSysDictListData()
    },
    changeInOut(val) {
      if (val) {
        this.form.inOut = true
      }
      let inout = false
      for (const item of this.table.data) {
        if (item.inOut) {
          inout = true
        }
      }
      if (!inout) {
        this.form.inOut = false
      }
    },
    changeRequired(val) {
      if (val) {
        this.form.required = true
      }
      let required = false
      for (const item of this.table.data) {
        if (item.required) {
          required = true
        }
      }
      if (!required) {
        this.form.required = false
      }
    },
    changeOneTwoManyRequired(val) {
      if (val) {
        this.oneToMany.required = true
      }
      let required = false
      for (const item of this.oneToMany.tableFieldList) {
        if (item.required) {
          required = true
        }
      }
      if (!required) {
        this.oneToMany.required = false
      }
    },
    // 生成代码
    generate() {
      this.$refs['formRules'].validate((valid) => {
        if (valid) {
          let primaryKeyName = null
          for (const item of this.table.data) {
            if (item.primaryKey) {
              primaryKeyName = item.columnName
            }
            if (item.fieldShowType === '') {
              item.fieldShowType = null
            }
            if (item.fieldInputType === '') {
              item.fieldInputType = null
            }
          }
          generateCode({
            table_name: this.form.tableName,
            moduleName: this.form.moduleName,
            tableComment: this.form.tableComment,
            inOut: this.form.inOut,
            required: this.form.required,
            primaryKeyCreatePolicy: this.form.primaryKeyCreatePolicy,
            primaryKeyName: primaryKeyName,
            tableFieldList: this.table.data,
            oneToManyTableDto: this.oneToMany
          }).then(res => {
            console.log('生成代码返回结果=', res)
            this.$message.success('生成成功')
          })
        } else {
          console.log('error submit!!')
          return false
        }
      })
    },
    // 查询表字段
    getFieldByTableData(tableName) {
      return new Promise((resolve, reject) => {
        getFieldByTable({
          tableName: tableName
        }).then(res => {
          const rows = res.rows
          for (const item of rows) {
            item.fieldSearchType = null
            item.joinDict = ''
            // 默认选中
            item.fieldShowType = this.defaultFieldShowType
            // 默认不选中导入导出功能
            item.inOut = false
            // 默认不设置非空校验
            item.required = false
          }
          resolve(rows)
        }).catch(res => {
          reject(res)
        })
      })
    },
    getAllTableData() {
      getAllTable().then(res => {
        this.allTableArray = res.rows
      })
    },
    changeTableJoinDictSelect(index) {
      if (this.table.data[index].joinDict !== null &&
        this.table.data[index].joinDict !== undefined &&
        this.table.data[index].joinDict !== '') {
        // 查询字段下拉
        this.$set(this.table.data[index], 'fieldSearchType', 'SELECT')
        // 输入字段下拉
        this.$set(this.table.data[index], 'fieldInputType', 'SELECT')
        // 列表显示类型为文本
        this.$set(this.table.data[index], 'fieldShowType', 'TEXT')
      } else {
        this.$set(this.table.data[index], 'fieldSearchType', '')
        this.$set(this.table.data[index], 'fieldInputType', '')
      }
    },
    changeOneToManyTableJoinDictSelect(index) {
      if (this.oneToMany.tableFieldList[index].joinDict !== null &&
        this.oneToMany.tableFieldList[index].joinDict !== undefined &&
        this.oneToMany.tableFieldList[index].joinDict !== '') {
        this.$set(this.oneToMany.tableFieldList[index], 'fieldSearchType', 'SELECT')
        this.$set(this.oneToMany.tableFieldList[index], 'fieldInputType', 'SELECT')
        this.$set(this.oneToMany.tableFieldList[index], 'fieldShowType', 'TEXT')
      } else {
        this.$set(this.oneToMany.tableFieldList[index], 'fieldSearchType', '')
        this.$set(this.oneToMany.tableFieldList[index], 'fieldInputType', '')
      }
    },
    /**
     * 列表查询变动
     */
    changeFieldSearchType(row) {
      if (row.fieldSearchType === 'SELECT') {
        if (row.joinDict === '') {
          row.fieldSearchType = ''
          this.$message.warning('下拉选不可主动选择，请设置关联字典')
        }
      }
    },
    /**
     * 添加/编辑变动
     */
    changeFieldInputType(row) {
      this.$set(row, 'fieldInputType', row.fieldInputType)
      if (row.fieldInputType === 'SELECT') {
        if (row.joinDict === '') {
          row.fieldInputType = 'INPUT'
          this.$message.warning('下拉选不可主动选择，请设置关联字典')
        }
        // 图片上传
      } else if (row.fieldInputType === 'IMAGE_UPLOAD') {
        row.fieldShowType = 'IMAGE'
        row.fieldSearchType = ''
        // 富文本
      } else if (row.fieldInputType === 'RICH_TEXT') {
        row.fieldShowType = null
        row.fieldSearchType = ''
        // 创建时间或者修改时间
      } else if (row.fieldInputType === 'CREATE_TIME' || row.fieldInputType === 'UPDATE_TIME') {
        row.fieldShowType = 'TEXT'
        row.required = false
        // row.fieldSearchType = ''
      }
    },
    changeFieldShowType(row) {
      if (row.fieldShowType === 'IMAGE') {
        row.fieldInputType = 'IMAGE_UPLOAD'
      }
    },
    changeJoinTable() {
      getFieldByTable({
        tableName: this.oneToMany.joinTable
      }).then(res => {
        this.getFieldByTableData(this.oneToMany.joinTable).then(rows => {
          this.oneToMany.tableFieldList = rows
        })
        const rows = res.rows
        this.oneToManyJoinFieldArray = rows
      })
    },
    // 查询列表显示字段类型
    getFieldShowTypeData() {
      getFieldShowType().then(res => {
        this.fieldShowTypeSelectArray = res.rows
        this.defaultFieldShowType = res.obj
        this.getFieldByTableData(this.form.tableName).then(rows => {
          this.table.data = rows
        })
      })
    },
    // 查询搜索字段类型
    getFieldSearchTypeData() {
      getFieldSearchType().then(res => {
        this.fieldSearchTypeSelectArray = res.rows
      })
    },
    // 查询输入字段类型
    getFieldInputTypeData() {
      getFieldInputType().then(res => {
        this.fieldInputTypeSelectArray = res.rows
      })
    },
    // 查询主键生成策略
    getPrimaryKeyCreatePolicyData() {
      getPrimaryKeyCreatePolicy().then(res => {
        this.primaryKeyCreatePolicySelectArray = res.rows
        // 设置默认值
        this.form.primaryKeyCreatePolicy = res.obj
        this.oneToMany.primaryKeyCreatePolicy = res.obj
      })
    },
    // 查询关联字典
    getSysDictListData() {
      getSysDictList().then(res => {
        this.joinDictSelectArray = res.rows
      })
    }
  }
}
</script>

<style scoped>

</style>
